//////////////////////////////////////////////////////////////////////////////////////////////
//	File			:	"Game.cpp"
//
//	Author			:	Mike Davis, Matt Stover, James Thornton, Keith Webster
//	
//	Project			:	TacWars
//
//	Last Modified	:	11/6/2013
//
//	Purpose			:	
//
//////////////////////////////////////////////////////////////////////////////////////////////
#include "Game.h"

#include "../SGD Wrappers/CSGD_Direct3D.h"
#include "../SGD Wrappers/CSGD_DirectInput.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "../SGD Wrappers/CSGD_XAudio2.h"
#include "../SGD Wrappers/CSGD_MessageSystem.h"
#include "../SGD Wrappers/CSGD_EventSystem.h"
#include "../source/MapSystem/BattleMap.h"
#include "StateMachine\IGameState.h"
#include "StateMachine\GameplayState.h"
#include "StateMachine\MainMenuState.h"
#include "GameObjects\Entity.h"
#include <cassert>
#include "MessageSystem\Message.h"
#include "MessageSystem\UnitDeadMessage.h"

//////////////////////////////
#include "GameObjects\General.h"
//////////////////////////////

Game* Game::Instance = nullptr;

Game* Game::GetInstance()
{
	if(Instance == nullptr)
		Instance = new Game;

	return Instance;
}
void Game::DeleteInstance()
{
	delete Instance;
	Instance = nullptr;
}
Game::Game()
{
	D3D = nullptr;
	DI = nullptr;
	TM = nullptr;
	XA =  nullptr;
	Font = nullptr;
	//yeah?
	//MS = nullptr;
	//ES = nullptr;
	screenWidth = screenHeight = 1;
	isWindowed = true;
	generalImgID = -1;
	GrassImgID = -1;
}
Game::~Game()
{
}
void Game::Initialize(HWND hWnd, HINSTANCE hInstance, int nWidth, int nHeight, bool bIsWindowed)
{
	D3D = CSGD_Direct3D::GetInstance();
	DI = CSGD_DirectInput::GetInstance();
	TM = CSGD_TextureManager::GetInstance();
	XA = CSGD_XAudio2::GetInstance();

	//cont
	//MS = CSGD_MessageSystem::GetInstance();
	//ES = CSGD_EventSystem::GetInstance();

	screenWidth = nWidth;
	screenHeight = nHeight;
	isWindowed = bIsWindowed;

	D3D->Initialize(hWnd, screenWidth, screenHeight, isWindowed, false);
	DI->Initialize(hWnd, hInstance, DI_KEYBOARD | DI_MOUSE | DI_JOYSTICKS);
	TM->Initialize(D3D->GetDirect3DDevice(), D3D->GetSprite());
	XA->Initialize();
	Font = new BitmapFont( _T("LargeGold"));
	Font->Initialize();

	generalImgID = TM->LoadTexture(_T("resource/Images/Commander.png"));
	knightImgID = TM->LoadTexture(_T("resource/Images/Tank.png"));
	rangerImgID = TM->LoadTexture(_T("resource/Images/Ranged.png"));
	priestImgID = TM->LoadTexture(_T("resource/Images/Healer.png"));
	berserkerImgID = TM->LoadTexture(_T("resource/Images/Melee.png"));
	partId = TM->LoadTexture(_T("resource/Particles/BFly.png"));



	//push first state here
	PushState(MainMenuState::GetInstance());
}
bool Game::Main()
{
	if(Input() == false)
		return false;

	Update();
	Render();
	return true;
}
void Game::Terminate()
{


	for(unsigned int i = StateVec.size(); i > 0; i--)
	{
		PopState();
	}

	if(Font != nullptr)
	{
		//Font->Shutdown();
		delete Font;
		Font = nullptr;
	}

	D3D->Terminate();
	TM->Terminate();
	DI->Terminate();
	XA->Terminate();

	D3D	= nullptr;
	TM	= nullptr;
	DI	= nullptr;
	XA	= nullptr;

	screenWidth = screenHeight = 1;
	isWindowed = true;

}
bool Game::Input()
{
	DI->ReadDevices();

	if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN) == true &&
		(CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT) == true ||
		CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT) == true))
	{
		isWindowed = !isWindowed;
		CSGD_Direct3D::GetInstance()->Resize(Game::GetInstance()->GetScreenWidth(), 
			Game::GetInstance()->GetScreenHeight(), isWindowed);
		return true;
	}

	return StateVec.back()->Input();
}
void Game::Update()
{
	XA->Update();

	DWORD now = GetTickCount();
	float fElapsedTime = (now - currTime) / 1000.0f;
	currTime = now;

	if( fElapsedTime > 0.125f )
		fElapsedTime = 0.125f;

	

	StateVec.back()->Update(fElapsedTime);
	//MS->ProcessMessages();
	//ES->ProcessEvents();
}
void Game::Render()
{
	D3D->Clear(D3DCOLOR_ARGB(255,50,50,50));

	D3D->DeviceBegin();
	D3D->SpriteBegin();

	//for(unsigned int i = 0; i < StateVec.size(); i++)
	//{
	//	StateVec[i]->Render();
	//}
	StateVec.back()->Render();
	D3D->SpriteEnd();
	D3D->DeviceEnd();

	D3D->Present();
}
void Game::PushState(IGameState* pState)
{
	StateVec.push_back(pState);
	if(StateVec.back() != nullptr)
		StateVec.back()->Enter();
}
void Game::PopState()
{
	StateVec.back()->Exit();
	StateVec.pop_back();
}
